package com.uwlaser.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.unit.DataUnit;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uwlaser.annotation.DateFormat;
import com.uwlaser.domain.*;
import com.uwlaser.service.DataMainService;
import com.uwlaser.service.DataMaterialSingleHistoryService;
import com.uwlaser.service.dto.*;
import com.uwlaser.service.mapper.DataMaterialSingleHistoryMapper;
import com.uwlaser.utils.*;
import lombok.AllArgsConstructor;
import com.uwlaser.base.PageInfo;
import com.uwlaser.base.QueryHelpMybatisPlus;
import com.uwlaser.base.impl.CommonServiceImpl;
import com.uwlaser.service.DataMaterialSingleService;
import com.uwlaser.service.mapper.DataMaterialSingleMapper;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* @author zk-Qin
* @date 2022-05-11
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = DataMaterialSingleService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DataMaterialSingleServiceImpl extends CommonServiceImpl<DataMaterialSingleMapper, DataMaterialSingle> implements DataMaterialSingleService {

    // private final RedisUtils redisUtils;
    private final DataMaterialSingleMapper dataMaterialSingleMapper;

    private final DataMainService dataMainService;

    private final DataMaterialSingleHistoryService dataMaterialSingleHistoryService;

    @Override
    public PageInfo<DataMaterialSingleDto> queryAll(DataMaterialSingleQueryParam query, Pageable pageable) {
        IPage<DataMaterialSingle> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<DataMaterialSingle> page = dataMaterialSingleMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, DataMaterialSingleDto.class);
    }

    @Override
    public List<DataMaterialSingleDto> queryAll(DataMaterialSingleQueryParam query){
        return ConvertUtil.convertList(dataMaterialSingleMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), DataMaterialSingleDto.class);
    }

    @Override
    public DataMaterialSingle getById(Integer id) {
        return dataMaterialSingleMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public DataMaterialSingleDto findById(Integer id) {
        return ConvertUtil.convert(getById(id), DataMaterialSingleDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(DataMaterialSingleDto resources) {
        DataMaterialSingle entity = ConvertUtil.convert(resources, DataMaterialSingle.class);
        return dataMaterialSingleMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(DataMaterialSingleDto resources){
        DataMaterialSingle entity = ConvertUtil.convert(resources, DataMaterialSingle.class);
        int ret = dataMaterialSingleMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids){
        // 通过id查出需要解绑的单件物料
        List<DataMaterialSingle> dataMaterialSingleList = dataMaterialSingleMapper.selectBatchIds(ids);
        List<DataMaterialSingleHistory> list = BeanCopyUtil.copyListToList(dataMaterialSingleList, DataMaterialSingleHistory.class);
        //新增物料数据（历史数据记录）
        dataMaterialSingleHistoryService.saveBatch(list);
        return dataMaterialSingleMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id){
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(Integer id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Integer> ids) {
        for (Integer id: ids) {
            delCaches(id);
        }
    }*/


    @Override
    public void download(List<DataMaterialSingleDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (DataMaterialSingleDto dataMaterialSingle : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("产品SN", dataMaterialSingle.getProductSn());
              map.put("产品型号", dataMaterialSingle.getProductCode());
              map.put("产品类型", dataMaterialSingle.getProductType());
              map.put("订单编号", dataMaterialSingle.getOrderCode());
              map.put("工单编号", dataMaterialSingle.getWorkOrderCode());
              map.put("产线编号", dataMaterialSingle.getLienCode());
              map.put("工段编号", dataMaterialSingle.getSectionCode());
              map.put("工位编号", dataMaterialSingle.getStationCode());
              map.put("工序编号", dataMaterialSingle.getOperationCode());
              map.put("设备编号", dataMaterialSingle.getDeviceCode());
              map.put("物料编号", dataMaterialSingle.getMaterialSn());
              map.put("物料名称", dataMaterialSingle.getMaterialName());
              map.put("物料编码", dataMaterialSingle.getMaterialCode());
              map.put("使用数量", dataMaterialSingle.getQuantity());
              map.put("扫描顺序", dataMaterialSingle.getScanNumber());
              map.put("物料单位", dataMaterialSingle.getMaterialUnit());
              map.put("过站ID", dataMaterialSingle.getPassStationId());
              map.put("创建人", dataMaterialSingle.getCreateBy());
              map.put("创建时间", dataMaterialSingle.getCreateTime());
              map.put("更新人", dataMaterialSingle.getUpdateBy());
              map.put("更新时间", dataMaterialSingle.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }

    @Override
    public DataMaterialSingle getProductSnByCell(DataRequestParam<GetProductSnByCellBatchParam> requestParam) {
        //获取电芯码集合
        @NotEmpty(message = "产品序号【productSns】不能为空！")
        List<String> productSns = requestParam.getParam().getProductSns();
        String cellCodes=new String();
        if(productSns.size()>0 && productSns!=null){
            //解析参数
            for (String productSn : productSns) {
                String code="\""+productSn+"\",";
                cellCodes+=code;
            }
            cellCodes=cellCodes.substring(0,cellCodes.length()-1);
        }
        List<DataMaterialSingle> dataMaterialSingles = dataMaterialSingleMapper.selectListByCellCode(cellCodes);
        if(dataMaterialSingles.size()>1){
            //查询到的绑定集合大于1说明这批电芯绑定了多个模组
            throw new RuntimeException("这批电芯存在重复绑定的模组");
        }else if(dataMaterialSingles.size()==0){
            throw new RuntimeException("MES中不存在绑定的模组");
        }
        //代码走到此处就说明正常获取到了模组码,在此处解绑托盘
        /*DataMainQueryParam queryParam=new DataMainQueryParam();
        if(requestParam.getParam().getTrayCode()!=null){
            queryParam.setTrayCode(requestParam.getParam().getTrayCode());
            //查询当前托盘本地是否存在绑定的模组
            List<DataMainDto> dataMainDtos = dataMainService.queryAll(queryParam);
            List<DataMain> dataMainList=new ArrayList<>();
            if(dataMainDtos.size()>0&& dataMainDtos!=null){
                for (DataMainDto dataMainDto : dataMainDtos) {
                    DataMain dataMain=new DataMain();
                    dataMain.setId(dataMainDto.getId());
                    dataMain.setTrayCode("Unbind");
                    dataMain.setUpdateBy(requestParam.getParam().getOperator());
                    dataMain.setUpdateTime(new Date());
                    dataMainList.add(dataMain);
                }
                //解绑托盘
                dataMainService.updateBatchById(dataMainList);
            }
        }*/
        return dataMaterialSingles.get(0);
    }

    @Override
    public List<DataMainDto> getProductSnByTray(DataRequestParam<GetProductSnByTrayCodeParam> requestParam) {
        //解析参数
        String trayCode = requestParam.getParam().getTrayCode();
        String aisleCode = requestParam.getParam().getAisleCode();
        DataMainQueryParam queryParam=new DataMainQueryParam();
        queryParam.setTrayCode(trayCode);
        queryParam.setAisleCode(aisleCode);
        List<DataMainDto> dataMainDtos = dataMainService.queryProductSn(queryParam);
        if(dataMainDtos.size()<1){
            if(aisleCode==null || "".equals(aisleCode)){
                throw new RuntimeException("托盘:["+trayCode+"]无绑定的模组");
            }else {
                throw new RuntimeException("托盘:["+trayCode+"]的["+aisleCode+"]通道无绑定的模组");
            }
        }
        return dataMainDtos;
    }

    @Override
    public DataMainDto getPackSnByTrayCode(DataRequestParam<GetPackSnByBoxCodeParam> requestParam) {
        //解析参数
        String trayCode=requestParam.getParam().getTrayCode();
        DataMainQueryParam queryParam=new DataMainQueryParam();
        queryParam.setTrayCode(trayCode);
        List<DataMainDto> dataMainDtos = dataMainService.queryPackSn(queryParam);
        if(dataMainDtos.size()==0){
            throw new RuntimeException(trayCode+":此托盘在MES中无绑定记录");
        }else if(dataMainDtos.size()>1){
            throw new RuntimeException(trayCode+"：此托盘在MES中存在多条绑定记录，请解绑后重试");
        }
        return dataMainDtos.get(0);

    }

    @Override
    public int unbindingTray(DataRequestParam<GetPackSnByBoxCodeParam> requestParam) {
        String trayCode = requestParam.getParam().getTrayCode();
        DataMainQueryParam queryParam=new DataMainQueryParam();
        queryParam.setTrayCode(trayCode);
        //查询当前托盘本地是否存在绑定的Pack
        List<DataMainDto> dataMainDtos = dataMainService.queryAll(queryParam);
        List<DataMain> dataMainList=new ArrayList<>();
        if(dataMainDtos.size()>0&& dataMainDtos!=null){
            for (DataMainDto dataMainDto : dataMainDtos) {
                DataMain dataMain=new DataMain();
                dataMain.setId(dataMainDto.getId());
                dataMain.setTrayCode("Unbind_"+trayCode);
                dataMain.setUpdateBy(requestParam.getParam().getOperator());
                dataMain.setUpdateTime(new Date());
                dataMainList.add(dataMain);
            }
            //解绑托盘
            boolean b = dataMainService.updateBatchById(dataMainList);
            if(b){
                return 1;
            }
        }else {
            //如果没有绑定记录，默认解绑成功
            return 1;
        }
        return 0;
    }
}
